<template>
  <ProTable
    ref="tableRef"
    :fetchListApi="_listQuickConfig"
    :columns="columns"
    row-key="id"
    :rowSelection="rowSelection"
  >
    <template #configType="{ record }">
      <template v-if="record.configType.includes('{')">
        <Tree :tree-data="JSON.parse(record.configType)" />
      </template>
      <template v-else>
        <Popover
          placement="right"
          trigger="hover"
          :overlayStyle="{ width: '100px' }"
          overlayClassName="popovper-dark"
          v-if="record.configType.split(',').length > 2"
        >
          <template #content>
            <ul>
              <li v-for="item in record.configType.split(',')">{{ item }}</li>
            </ul>
          </template>
          <div class="truncate w-full" v-html="record.configType"></div>
        </Popover>
        <div v-else class="truncate w-full" v-html="record.configType"></div>
      </template>
    </template>
    <template #modelAlwaysVOS="{ record }">
      <Tree
        v-if="record.modelAlwaysVOS && record.modelAlwaysVOS.length"
        :tree-data="record.modelAlwaysVOS"
        :field-names="fileNames"
      />
    </template>
    <template #toolbars>
      <Space>
        <b-button
          icon="import"
          @click="deviceListVisible = true"
          code="quickConfig:import"
          >导入配置</b-button
        >
        <b-button icon="add" @click="onAdd()" code="quickConfig:add"
          >新增</b-button
        >
        <b-button
          icon="delete"
          @click="onDelete()"
          :disabled="!selectRows.length"
          code="quickConfig:del"
          >删除</b-button
        >
      </Space>
    </template>
    <template #operation="{ record }">
      <b-button
        icon="detail"
        type="link"
        @click="onView(record)"
        code="quickConfig:getInfo"
        >查看</b-button
      >
      <b-button
        v-if="record.approvalStatus == 0"
        icon="remote"
        type="link"
        @click="handlePush(record)"
        code="quickConfig:check"
        >验证</b-button
      >
      <b-button
        icon="examine"
        type="link"
        @click="enableToggle(record)"
        code="quickConfig:enable"
        >启用/停用</b-button
      >
      <b-button
        v-if="record.approvalStatus == 0"
        icon="examine"
        type="link"
        @click="configAuditingConfig(record)"
        code="quickConfig:approval"
        >审批</b-button
      >
      <b-button
        icon="edit"
        type="link"
        @click="pushRecord(record)"
        code="quickConfig:log"
        >记录</b-button
      >
      <b-button
        icon="handle"
        type="link"
        @click="handleCopyConfig(record)"
        code="quickConfig:copy"
        >拷贝</b-button
      >
    </template>
  </ProTable>
  <FormModal :items="items" />
  <Modal
    title="快速配置"
    v-model:open="configTabsVisible"
    v-if="configTabsVisible"
    :width="1400"
    :mask-closable="false"
    :keyboard="false"
    :footer="null"
    centered
    destroy-on-close
    class="deviceTabsModal modal-tab-bg"
  >
    <ConfigTabs :page-data="pageDate" :type="type" @close="configTabsClose" />
  </Modal>
  <Modal
    title="推送记录"
    v-model:open="pushRecordVisible"
    :width="1400"
    :mask-closable="false"
    :keyboard="false"
    :footer="null"
    centered
    destroy-on-close
  >
    <PushRecord :page-data="pageDate" @handleCheck="handleCheck" />
  </Modal>
  <Modal
    :title="failTitle"
    v-model:open="pushDeviceVisible"
    :width="1400"
    :mask-closable="false"
    :keyboard="false"
    :footer="null"
    centered
    destroy-on-close
  >
    <PushDevice :page-data="pushDeviceData" />
  </Modal>
  <Modal
    title="设备列表"
    v-model:open="deviceListVisible"
    :width="1600"
    :mask-closable="false"
    :keyboard="false"
    :footer="null"
    centered
    destroy-on-close
    v-if="deviceListVisible"
  >
    <DeviceList @select="selectDevice" />
  </Modal>
  <Modal
    :title="failTitle"
    v-model:open="pushConfigVisible"
    :width="1600"
    :mask-closable="false"
    :keyboard="false"
    :footer="null"
    centered
    destroy-on-close
  >
    <PushConfig
      :page-data="pageDate"
      @pushSuccess="pushSuccess"
      @close="pushConfigVisible = false"
    />
  </Modal>
</template>

<script setup lang="tsx">
import { computed, nextTick, ref } from 'vue';
import { Modal, Popover, Space, Tag, Tree, message } from 'ant-design-vue';
import { ProFormProps } from '@/components/ProForm';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import { useFormModal } from '@/hooks/formModal';
import { protobufVersionEnum, statusEnum } from '@/constant/push';
import {
  ApprovalConfig,
  delQuickConfig,
  getSelectDeviceConfig,
  listQuickConfig,
  quickConfigEnable,
} from '@/api/push';
import ConfigTabs from './components/ConfigTabs.vue';
import DeviceList from './components/DeviceList.vue';
import PushConfig from './components/PushConfig.vue';
import PushDevice from './components/PushDevice.vue';
import PushRecord from './components/PushRecord.vue';

const pageDate: any = ref({});
const failTitle: any = ref('');
const pushDeviceData: any = ref({});
const type = ref('');
const configTabsVisible = ref(false);
const pushRecordVisible = ref(false);
const pushDeviceVisible = ref(false);
const deviceListVisible = ref(false);
const pushConfigVisible = ref(false);
const selectRows = ref<any[]>([]);
const isOffline = ref(false);
const rowSelection = ref<ProTableProps['rowSelection']>({
  onChange(values, selectedRows) {
    selectRows.value = selectedRows;
    isOffline.value = selectedRows.some((item) => {
      return item.onlineStatus == '0';
    });
  },
});
const tableRef = ref();
const _listQuickConfig = async (params: any) => {
  const startTime = params.createTime?.[0];
  const endTime = params.createTime?.[1];
  const res = await listQuickConfig({
    ...params,
    startTime,
    endTime,
    createTime: undefined,
  });
  res.rows.forEach((item: any) => {
    if (item.modelAlwaysVOS) {
      item.modelAlwaysVOS.forEach((model: any) => {
        model.typeName = `${model.typeName}(${model.modeName.length})`;
        model.modeName = model.modeName.map((name: any) => {
          return {
            typeName: name,
          };
        });
      });
    }
  });
  return res;
};

const fileNames = {
  title: 'typeName',
  children: 'modeName',
};
const columns = computed<ProTableProps['columns']>(() => [
  {
    title: '配置编码ID',
    dataIndex: 'code',
  },
  {
    title: '协议版本',
    dataIndex: 'protobufVersion',
    valueEnum: protobufVersionEnum,
    customRender({ text }) {
      return text
        .split(',')
        .map((item: any) => protobufVersionEnum[item])
        .join();
    },
    width: 80,
  },
  {
    title: '设备类型/设备型号',
    dataIndex: 'modelAlwaysVOS',
    hideInSearch: true,
    width: 160,
  },
  {
    title: '配置说明',
    dataIndex: 'configExplain',
  },
  {
    title: '配置类别',
    dataIndex: 'configType',
    hideInSearch: true,
    width: 150,
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    isTime: true,
  },
  {
    title: '审批状态',
    dataIndex: 'approvalStatus',
    valueEnum: { 0: '待审批', 1: '审批通过', 2: '审批不通过' },
    width: 80,
  },
  {
    title: '审批时间',
    dataIndex: 'approvalTime',
    hideInSearch: true,
    isTime: true,
  },
  {
    title: '是否启用',
    dataIndex: 'status',
    valueEnum: statusEnum,
    defaultValue: '1',
    width: 100,
    customRender({ text }) {
      return (
        <Tag color={text == '1' ? 'success' : 'error'}>
          {statusEnum[text as keyof typeof statusEnum]}
        </Tag>
      );
    },
  },
  {
    title: '操作',
    dataIndex: 'operation',
    hideInSearch: true,
    fixed: 'right',
    width: 450,
  },
]);

const items = computed<ProFormProps['items']>(() => [
  {
    label: '审核结果',
    type: 'radio',
    field: 'approvalStatus',
    props: {
      options: [
        { value: 1, label: '审批通过' },
        { value: 2, label: '审批不通过' },
      ],
    },
    rules: [
      {
        required: true,
        message: `请选择审核结果`,
        trigger: 'blur',
      },
    ],
  },
]);
const { FormModal, open } = useFormModal({
  size: 'mini',
  column: 1,
  formProps: { labelCol: { span: 6 } },
});
const newConfigObj = (obj: any) => {
  const newObj: any = {};
  const keys: Array<string> = [
    'mqttConfigsJson',
    'nettyConfigsJson',
    'fileConfigsJson',
    'gpsConfigsJson',
    'ntpConfigsJson',
    'weatherConfigsJson',
    'warnConfigsJson',
    'reportConfigsJson',
    'volumeConfigsJson',
    'energyConfigsJson',
    'deviceConfigsJson',
    'videoConfigsJson',
    'meshConfigsJson',
    'intensityMeterConfigMessagesJson',
    'brandConfigsJson',
    'gpioControlConfigsJson',
  ];
  for (let key of keys) {
    newObj[key] = obj[key] ?? '{}';
  }
  newObj.configExplain = obj.configExplain ?? '';
  newObj.configType = obj.configType ?? '';
  newObj.runningModeConfigsJson =
    obj.runningModeConfigsJson ?? '{"runningMode":"0"}';
  newObj.themeConfigsJson = obj.themeConfigsJson ?? '{"theme":"1"}';
  newObj.gpioControlConfigsJson =
    obj.gpioControlConfigsJson ??
    '{"gpio1Config":"0,0,0,0,0,0,0","gpio2Config":"0,0,0,0,0,0,0","gpio3Config":"0,0,0,0,0,0,0","gpio4Config":"0,0,0,0,0,0,0"}';
  newObj.mqttConfigsJson =
    obj.mqttConfigsJson ??
    '{"serverConfig":{},"mainMqttConfig":{},"alternateMqttConfig":{},"warnTopicConfig":{},"drillTopicConfig":{},"authConfig":{},"warnSafeConfig":{"cartesianConfig":{}}}';
  newObj.protobufVersion = obj.protobufVersion ?? '1';
  newObj.deviceType = 2;
  return newObj;
};
const onAdd = () => {
  pageDate.value = newConfigObj({});
  type.value = 'add';
  configTabsVisible.value = true;
};
const onView = (record: any) => {
  const mqttConfig =
    record.protobufVersion < 2
      ? '{}'
      : '{"serverConfig":{},"mainMqttConfig":{},"alternateMqttConfig":{},"warnTopicConfig":{},"drillTopicConfig":{},"authConfig":{},"warnSafeConfig":{"cartesianConfig":{}}}';
  pageDate.value = {
    ...record,
    runningModeConfigsJson:
      record.runningModeConfigsJson || '{"runningMode":"0"}',
    themeConfigsJson: record.themeConfigsJson || '{"theme":"1"}',
    mqttConfigsJson: record.mqttConfigsJson || mqttConfig,
    nettyConfigsJson: record.nettyConfigsJson || '{}',
    fileConfigsJson: record.fileConfigsJson || '{}',
    gpsConfigsJson: record.gpsConfigsJson || '{}',
    ntpConfigsJson: record.ntpConfigsJson || '{}',
    weatherConfigsJson: record.weatherConfigsJson || '{}',
    warnConfigsJson: record.warnConfigsJson || '{}',
    reportConfigsJson: record.reportConfigsJson || '{}',
    volumeConfigsJson: record.volumeConfigsJson || '{}',
    energyConfigsJson: record.energyConfigsJson || '{}',
    deviceConfigsJson: record.deviceConfigsJson || '{}',
    videoConfigsJson: record.videoConfigsJson || '{}',
    meshConfigsJson: record.meshConfigsJson || '{}',
    intensityMeterConfigMessagesJson:
      record.intensityMeterConfigMessagesJson || '{}',
    brandConfigsJson: record.brandConfigsJson || '{}',
    gpioControlConfigsJson:
      record.gpioControlConfigsJson ||
      '{"gpio1Config":"0,0,0,0,0,0,0","gpio2Config":"0,0,0,0,0,0,0","gpio3Config":"0,0,0,0,0,0,0","gpio4Config":"0,0,0,0,0,0,0"}',
  };
  type.value = 'info';
  configTabsVisible.value = true;
};
const configTabsClose = (refresh: boolean) => {
  configTabsVisible.value = false;
  refresh && sleep(() => tableRef.value.refresh());
};
const configAuditingConfig = (record: any) => {
  open({
    title: '审核',
    defaultValue: { id: record.id },
    serviceApi: async (params: any): Promise<any> => {
      const _params = new FormData();
      Object.keys(params).forEach((key) => {
        _params.append(key, params[key]);
      });
      await ApprovalConfig(_params);
      sleep(() => tableRef.value.refresh());
    },
  });
};
const enableToggle = async (record: any) => {
  const id = record.id;
  const status = record.status == '1' ? '0' : '1';
  await quickConfigEnable({ id, status });
  message.success('操作成功');
  tableRef.value.refresh();
};

const pushRecord = (record: any) => {
  pageDate.value = { ...record };
  pushRecordVisible.value = true;
};

const handlePush = (record: any) => {
  pageDate.value = { ...record };
  failTitle.value = '验证';
  pushConfigVisible.value = true;
};
const handleCopyConfig = (record: any) => {
  pageDate.value = newConfigObj(record);
  type.value = 'add';
  configTabsVisible.value = true;
};

const selectDevice = async (row: any) => {
  const code = row.code;
  const res = await getSelectDeviceConfig({ code });
  const selectData: any = res.data;
  const mqttConfig =
    row.protobufVersion < 2
      ? {}
      : {
          serverConfig: {},
          mainMqttConfig: {},
          alternateMqttConfig: {},
          warnTopicConfig: {},
          drillTopicConfig: {},
          authConfig: {},
          warnSafeConfig: {
            cartesianConfig: {},
          },
        };
  pageDate.value = {
    runningModeConfigsJson: JSON.stringify(
      selectData.runningModeConfig || { runningMode: '0' },
    ),
    themeConfigsJson: JSON.stringify(selectData.themeConfig || { theme: '1' }),
    mqttConfigsJson: JSON.stringify(selectData.mqttConfig || mqttConfig),
    nettyConfigsJson: JSON.stringify(selectData.nettyConfig || {}),
    fileConfigsJson: JSON.stringify(selectData.fileConfig || {}),
    gpsConfigsJson: JSON.stringify(selectData.gpsConfig || {}),
    ntpConfigsJson: JSON.stringify(selectData.ntpConfig || {}),
    weatherConfigsJson: JSON.stringify(
      selectData.weatherConfig || { isOpen: '0', code: null },
    ),
    warnConfigsJson: JSON.stringify(selectData.warnConfig || {}),
    reportConfigsJson: JSON.stringify(selectData.reportConfig || {}),
    volumeConfigsJson: JSON.stringify(selectData.volumeConfig || {}),
    energyConfigsJson: JSON.stringify(selectData.energyConfig || {}),
    deviceConfigsJson: JSON.stringify(selectData.deviceConfig || {}),
    videoConfigsJson: JSON.stringify(selectData.videoConfig || {}),
    meshConfigsJson: JSON.stringify({
      isOpenMesh: selectData.meshConfig?.isOpenMesh,
    }),
    intensityMeterConfigMessagesJson: JSON.stringify(
      selectData.meterConfig || {},
    ),
    brandConfigsJson: JSON.stringify(selectData.meshConfig || {}),
    gpioControlConfigsJson: JSON.stringify(
      selectData.gpioConfig || {
        gpio1Config: '0,0,0,0,0,0,0',
        gpio2Config: '0,0,0,0,0,0,0',
        gpio3Config: '0,0,0,0,0,0,0',
        gpio4Config: '0,0,0,0,0,0,0',
      },
    ),
    configExplain: '',
    protobufVersion: row.protobufVersion,
    deviceType: 2,
    configType: selectData.configType || [],
    modelIds: [row.modelId],
  };
  type.value = 'add';
  deviceListVisible.value = false;
  nextTick(() => {
    configTabsVisible.value = true;
  });
};

const handleCheck = (row: any, sta: any) => {
  pushDeviceData.value = row;
  if (sta == '0') {
    pushDeviceData.value.upgradeStatus = sta;
    failTitle.value = '推送失败设备列表';
  } else {
    pushDeviceData.value.upgradeStatus = '';
    failTitle.value = '推送设备列表';
  }
  pushDeviceVisible.value = true;
};

const pushSuccess = (row: any) => {
  sleep(() => tableRef.value.refresh());
  pushConfigVisible.value = false;
  pushDeviceData.value = row;
  failTitle.value = '推送结果';
  pushDeviceVisible.value = true;
};

const sleep = (cb, time = 500) => {
  setTimeout(() => {
    cb();
  }, time);
};
const onDelete = async () => {
  const ids = selectRows.value.map((item) => item.id).join();
  Modal.confirm({
    title: '系统提示',
    centered: true,
    content: `是否确认勾选删除配置？`,
    onOk: async () => {
      await delQuickConfig({ ids });
      sleep(() => tableRef.value.refresh());
      message.success('操作成功');
    },
  });
};
</script>
